<html><head>
<title>Peeko PI Computer v0.1.6</title>
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/keyboard.js"></script>
<script type="text/javascript" src="js/instructions_hex.js"></script>
<script type="text/javascript" src="js/raspi.js"></script>
<script type="text/javascript" src="js/peeko_pi.js"></script>
<script type="text/javascript" src="js/jquery.fancybox.pack.js"></script>
<script type="text/javascript" src="js/jquery.jeditable.mini.js"></script>
<link rel="stylesheet" href="css/jquery.fancybox.css" type="text/css" media="screen" />
<link rel="stylesheet" href="css/style_v2.css" type="text/css">
<link rel="stylesheet" href="css/controls.css" type="text/css">
<link rel="stylesheet" href="css/led.css" type="text/css">
<link href='http://fonts.googleapis.com/css?family=Raleway:400,500' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700' rel='stylesheet' type='text/css'>
</head><body>
<script>
var exec_timer;
var delayTime;

var boardRev = 2;

// used at the start, and after every program load
function init_ui() {
	delayTime = 500;
	update_display();
}

// how is this related to update_status() in the js/peeko_v2.js file ?
function update_display() {
	$('#pc').text(get_pc().toString(16));
	highlight_pc();
	$('#mnemonic').text(decode_mnemonic(get_pc()));
	$('#accumulator').text(get_accumulator().toString(16));
	$('#carry').text(get_carry_flag());
	$('#zero').text(get_zero_flag());

	$('#status').text(get_program_state());
	$('#stepdelay').text(delayTime);
	$('#stepcount').text(get_step_count());
}

// bump this into generic, or too UI specific ?
function get_hex_pc() {
	var pc = get_pc();
	if (pc < 16) {
		pc = "0" + pc.toString(16);
	} else {
		pc = pc.toString(16);
	}
	return(pc);
}

function highlight_pc(addr) {
	$('td').removeClass('pc');
	if (arguments.length == 0) {
		$('#' + get_hex_pc()).addClass('pc');
	} else {
		if (addr < 16) {
			addr = "0" + addr.toString(16);
		} else {
			addr = addr.toString(16);
		}
		$('#' + addr).addClass('pc');
	}
}

function one_step() {
	execute_pc();
	highlight_pc();
	update_display();
	if (programState.RUN == get_run_mode()) {
		setTimeout(one_step, delayTime);
	}
}

function save_program() {
	var title = $('#file_title').val();
	var descr = $('#file_description').val();
	if (title.length > 0) {
		save_state();
		$.fancybox.close();
	}
}

function load_program() {
	load_state();
	$.fancybox.close();
	init_ui();
}

function start_execution() {
	if (programState.RUN != get_run_mode()) {
		delayTime = parseInt($('#stepdelay').text());
		set_run_mode(programState.RUN);
		set_pc($('#pc').text());
		set_carry_flag($('#carry').text());
		set_zero_flag($('#zero').text());
		set_step_count(0);
		one_step();
	}
}

function stop_execution() {
	set_run_mode(programState.READY);
	update_display();
}

// do we want to halt as well, or just do it regardless ?
function reset_pc() {
	if (programState.RUN == get_run_mode()) {
		set_run_mode(programState.READY);
	}
	set_pc(0);
	update_display();
	// also set the output display to zero ?
}

function speedup_execution() {
	delayTime = parseInt($('#stepdelay').text());
	delayTime -= 50;
	if (delayTime < 50) delayTime = 50;
	$('#stepdelay').text(delayTime);
	update_status();
}

function show_popup(t) {
	var decoded = decode_mnemonic(parseInt("0x" + t.id));
	$('#cursor').text(decoded);
}

function remove_popup(t) {
	$('#cursor').text("");
}

function swap_instructions() {
	var source = parseInt("0x" + $('#cnum').val());
	var dest = parseInt("0x" + $('#fnum').val());
	if ((source >= 0) && (source < 16)) {
		if ((dest >= 0) && (dest < instructionSet.length)) {
			change_instruction(source, dest);
			$('#cnum').val('');
			$('#fnum').val('');
		}
	}
	$('#instset').html(get_instruction_set(true, 8));
	$('#edit_set_cur').html(get_instruction_set(true, 0));
	$('#edit_set_full').html(get_all_instructions(true, 0));
	update_status();
}

// M A I N
$(function() {
	init();
	$('.fancybox').fancybox();

	var newRow;
	for (var hi=-1; hi<(get_HIMEM() / 16); hi++) {
		if (hi < 0) {
			newRow = '<tr><th>H/L</th>';
		} else {
			newRow = '<tr><th>' + hi + '</th>';
		}
		for (var lo=0; lo<16; lo++) {
			if (hi < 0) {
				newRow += '<th>' + lo.toString(16) + '</th>';
			} else {
				newRow += '<td onMouseOver="show_popup(this)" onMouseOut="remove_popup(this)" class="editcell" id="' + hi + lo.toString(16) + '">0</td>';
			}
		}
		newRow += '</tr>';
		$('#memory > tbody:last').append(newRow);
	}

	for (var hi=-1; hi<1; hi++) {
		if (hi < 0) {
			newRow = '<tr><th>GPIO</th>';
		} else {
			newRow = '<tr><th></th>';
		}
		for (var lo=0; lo<16; lo++) {
			if (hi < 0) {
				newRow += '<th>' + lo.toString(16) + '</th>';
			} else {
				if ((lo < 2) || (lo > 9)) {
					newRow += '<td id="p' + hi + lo.toString(16) + '">0</td>';
				} else {
					newRow += '<td id="p' + hi + lo.toString(16) + '">LED' + (lo - 2) + '</td>';
				}
			}
		}
		newRow += '</tr>';
		$('#ports > tbody:last').append(newRow);
		for (var i=2; i<10; i++) {
			set_port(i, 6);
		}
	}

	$('.editcell').editable(function(value, settings) {
		value = parseInt("0x" + value) || 0;
		if (value < 0)
			value = 0;
		if (value > 15)
			value = 0;
		return(value.toString(16));
	}, {
		type: "text",
		select: true,
		onblur: 'submit',
		height: "1.9em",
		width: "1.7em",
		callback: function(value, settings) {
			$('#mnemonic').text(decode_mnemonic());
		},
	});
	$('.editflag').editable(function(value, settings) {
		value = parseInt(value) || 0;
		if (value < 0)
			value = 0;
		if (value > 1)
			value = 1;
		return(value);
	}, {
		type: "text",
		select: true,
		onblur: 'submit',
		height: "1.9em",
		width: "1.7em",
	});
	$('.editnum').editable(function(value, settings) {
		value = parseInt("0x" + value) || 0;
		highlight_pc(value);
		return(value.toString(16));
	}, {
		type: "text",
		select: true,
		onblur: 'submit',
		height: "1.9em",
		width: "3.7em",
		callback: function(value, settings) {
			$('#mnemonic').text(decode_mnemonic());
			//highlight_pc();
		},
	});
	$('.editdec').editable(function(value, settings) {
		value = parseInt(value) || 0;
		// FIXME: this should be a decimal entry, not a custom delay entry
		delayTime = value;
		return(value);
	}, {
		type: "text",
		select: true,
		onblur: 'submit',
		height: "1.9em",
		width: "3.7em",
	});

	$('#instset').html(get_instruction_set(true, 8));
	$('#edit_set_cur').html(get_instruction_set(true, 0));
	$('#edit_set_full').html(get_all_instructions(true, 0));

	// needs to be dynamic, after the main table draw
	$('.outerbox').css('float', 'left');

	// trap TAB entries
	$(".editcell").bind('keydown', function(e) {
		if (9 == e.keyCode) {
			var numcell = parseInt("0x" + this.id);
			numcell++;
			numcell = numcell % get_HIMEM();
			if (numcell < 16) {
				numcell = "#0" + numcell.toString(16);
			} else {
				numcell = "#" + numcell.toString(16);
			}
			$(this).find("input").blur();
			$(numcell).click();
			return false;
		}
	});

	// FIXME: would be good to catch ENTER and force edit on cell under PC - need to check not running

	init_ui();
});
</script>
<div class="leftcol">
 <div class="outerboxfix">
  <div class="title">System <b>Memory</b></div>
  <table id="memory" class="memory">
   <tbody></tbody>
  </table>
 </div>

 <div class="outerboxfix">
  <div class="title">System <b>Ports</b></div>
  <table id="ports" class="ports">
   <tbody></tbody>
  </table>
 </div>
</div>

<div class="rightcol">
 <div class="outerboxfix">
  <div class="title">System <b>Info</b></div>
  <table class="sysinfo">
   <tr>
    <th>PC:</th><td class="editnum" id="pc"></td><td id="mnemonic"></td>
   </tr>
   <tr>
    <th>Cursor:</th><td colspan="2" id="cursor"></td>
   </tr>
   <tr>
    <th>Accumulator:</th><td colspan="2" class="editcell" id="accumulator"></td>
   </tr>
   <tr>
    <th>Carry Flag:</th><td colspan="2" class="editflag" id="carry"></td>
   </tr>
   <tr>
    <th>Zero Flag:</th><td colspan="2" class="editflag" id="zero"></td>
   </tr>
   <tr>
    <th>Output:</th><td colspan="2" id="outputdisplay">00000000</td>
   </tr>
  </table>
 </div>

 <div class="outerboxfix">
  <div class="title">System <b>Control</b></div>
  <table class="control">
   <tr>
    <th>Control:</th>
    <td valign="top">
     <ul id="controls">
      <li id="resetpc"><a href="#non" onClick="reset_pc();"></a></li>
      <li id="start"><a href="#non" onClick="start_execution();"></a></li>
      <li id="speedup"><a href="#non" onClick="speedup_execution();"></a></li>
      <li id="stop"><a href="#non" onClick="stop_execution();"></a></li>
     </ul>
    </td>
   </tr>
  </table>
</div>

 <div class="outerboxfix">
  <div class="title">System <b>Status</b></div>
  <table class="status">
   <tr>
    <th>Status:</th><td colspan="2" id="status"></td>
   </tr>
   <tr>
    <th>Steps:</th><td colspan="2" id="stepcount"></td>
   </tr>
   <tr>
    <th>Program:</th><td id="save"><a href="#save_popup" class="fancybox">SAVE</a></td><td id="load"><a href="#load_popup" class="fancybox">LOAD</a></td>
   </tr>
   <tr>
    <th>Delay:</th><td class="editdec" id="stepdelay"></td><th>ms</th>
   </tr>
  </table>
 </div>
</div>

<div class="outerbox">
 <div class="title">Help <b>Summary</b></div>
 <ul>
  <li>Click on any of the System Memory location calls to edit the value in that location</li>
  <li>Click on the Program Counter (PC) to set the value to start from on the next run</li>
  <li>Editing any cell will halt the current execution (if started)</li>
  <li>Change the pause time between each instruction by editing the <b>Delay:</b> value</li>
  <li>Click on the <b>Status:</b> message to start and stop an execution run</li>
 </ul>
</div>

<div class="outerbox">
 <div class="title">Current <b>Instructions</b></div>
 <div id="instset"></div>
 <div style="font-family: Verdana, sans-serif; font-size: 80%; padding-left: 20px; padding-bottom: 5px;"><a href="#edit_set" class="fancybox">Edit Set</a></div>
</div>

<div id="edit_set" style="display:none">
 <table id="edit_set_table" class="swap_set">
  <thead>
   <tr>
    <td>Current</td><td>Full List</td>
   </tr>
  </thead>
  <tbody>
   <tr><td valign="top" id="edit_set_cur"></td><td valign="top" id="edit_set_full"></td></tr>
  </tbody>
  <tfoot>
   <tr><td><input id="cnum" type="text" size="3" maxlength="1"></td><td><input id="fnum" type="text" size="3" maxlength="2"></td></tr>
   <tr><td colspan="2"><input type="button" value="Swap" onClick="swap_instructions();"></td></tr>
  </tfoot>
 </table>
</div>

<div id="save_popup" style="display:none">
 <table class="swap_set">
  <thead>
   <tr>
    <td colspan="2">Save Program</td>
   </tr>
  </thead>
  <tr>
   <td>Program Title:</td>
   <td><input id="file_title" type="text" size="40"></td>
  </tr>
  <tr>
   <td>Program Description:</td>
   <td><textarea id="file_description" cols="40" rows="5"></textarea></td>
  </tr>
  <tr>
   <td><input type="button" value="Save" onClick="save_program();"></td>
  </tr>
 </table>
</div>

<div id="load_popup" style="display:none"></div>
</body></html>
